package mobi.greenplate.theweb.resource;

import java.net.URI;
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import mobi.greenplate.theweb.converter.AddressConverter;
import mobi.greenplate.theweb.converter.AddressListConverter;
import mobi.greenplate.theweb.domain.Address;
import mobi.greenplate.theweb.repository.AddressRepository;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

@Path("/address")
@Component
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class AddressResource {

    @Inject
    private AddressRepository addressRepository;
    @Context
    private UriInfo uriInfo;

    @GET
    @Produces({"application/xml", "application/json"})
    public AddressListConverter getAddresss(@QueryParam("first") @DefaultValue("0") int first,
            @QueryParam("max") @DefaultValue("10") int max) {
        final List<Address> addressList = addressRepository.findAll(first, max);
        final AddressListConverter addressListConverter = new AddressListConverter(addressList);
        return addressListConverter;
    }

    @GET
    @Produces({"application/xml", "application/json"})
    @Path("{id}")
    public AddressConverter getAddressById(@PathParam("id") Long id) {
        try {
            final Address address = addressRepository.findById(id);
            final AddressConverter addressConverter = new AddressConverter(address);
            return addressConverter;
        } catch (IllegalArgumentException ex) {
            throw new NotFoundException(ex.getMessage());
        }
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    public Response createAddress(AddressConverter addressConverter) {
        final Address forSave = addressConverter.getEntity();
        forSave.setId(null); //makes sure it is allways new..
        final Address address = addressRepository.save(forSave);
        final URI uri = uriInfo.getAbsolutePathBuilder().
                path(address.getId().toString()).
                build();
        return Response.created(uri).build();
    }

    @PUT
    @Consumes({"application/xml", "application/json"})
    @Path("{id}")
    public AddressConverter updateOrCreateAddress(@PathParam("id") Long id, AddressConverter addressConverter) {
        //if the resource doesn't exist.. it would be created...with PUT.. could be added additional check ...
        final Address forSave = addressConverter.getEntity();
        forSave.setId(id); //makes sure it is exactly the one that has to be updated
        final Address address = addressRepository.save(forSave);
        return new AddressConverter(address);
    }

    @DELETE
    @Path("{id}")
    public void deleteAddress(@PathParam("id") Long id) {
        addressRepository.delete(id);
    }
}
